package org.mybatis.generator.codegen.spring.jdbc.repository.elements;

import static org.mybatis.generator.internal.util.JavaBeansUtil.getGetterMethodName;

import java.util.List;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.codegen.spring.jdbc.repository.AbstractRepGenerator;

public class InsertMethodGenerator extends AbstractRepGenerator {
	boolean isSimple = false;

	public InsertMethodGenerator(boolean isSimple) {
		super();
		this.isSimple = isSimple;
	}

	@Override
	public void addImplementationElements(TopLevelClass topLevelClass) {
		//String domainObjectName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
		// FullyQualifiedJavaType returnType = new FullyQualifiedJavaType(domainObjectName);
		// FullyQualifiedJavaType parameterType = new FullyQualifiedJavaType(domainObjectName);
		FullyQualifiedJavaType returnType =introspectedTable.getRules().calculateAllFieldsClass();
		FullyQualifiedJavaType parameterType;
		if (isSimple) {
			parameterType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
		} else {
			parameterType = introspectedTable.getRules().calculateAllFieldsClass();
		}
		topLevelClass.addImportedType(returnType);
		topLevelClass.addImportedType(parameterType);
		// 添加依赖类
		addImportedType(topLevelClass);
		// 获得主键信息
		List<IntrospectedColumn> pks = introspectedTable.getPrimaryKeyColumns();

		// 设置方法
		Method method = new Method();

		method.setVisibility(JavaVisibility.PUBLIC);
		method.setReturnType(returnType);
		method.setName("insert");
		method.addParameter(new Parameter(parameterType, "entity"));
		method.addException(new FullyQualifiedJavaType("org.springframework.dao.DataAccessException"));
		// 方法内部代码
		/*
		 * Map<String, Object> parameters = new HashMap<String, Object>(3);
		 * parameters.put("id", actor.getId()); parameters.put("first_name",
		 * actor.getFirstName()); parameters.put("last_name",
		 * actor.getLastName()); insertActor.execute(parameters);
		 */
		StringBuilder sb = new StringBuilder();
		method.addBodyLine("Map<String, Object> parameters = new HashMap<String, Object>();");
		List<IntrospectedColumn> iterable = introspectedTable.getAllColumns();
		for (int i = 0, size = iterable.size(); i < size; i++) {
			IntrospectedColumn element = iterable.get(i);
			sb.setLength(0);
			sb.append("parameters.put(\"");
			sb.append(element.getActualColumnName());
			sb.append("\" ,entity.");
			sb.append(getGetterMethodName(element.getJavaProperty(), element.getFullyQualifiedJavaType()));
			sb.append("());");
			method.addBodyLine(sb.toString());

		}
		method.addBodyLine("this.simpleJdbcInsert.execute(parameters);");

		if (introspectedTable.getRules().generateSelectByPrimaryKey()) {
			sb.setLength(0);
			sb.append("entity = findOneById(");
			for (int i = 0; i < pks.size(); i++) {
				IntrospectedColumn introspectedColumn = pks.get(i);
				if (i != 0) {
					sb.append(" , ");
				}
				sb.append("entity.");
				sb.append(getGetterMethodName(introspectedColumn.getJavaProperty(),
				        introspectedColumn.getFullyQualifiedJavaType()));
				sb.append("()");
			}
			sb.append(");");
		}
		method.addBodyLine(sb.toString());
		method.addBodyLine("return entity;");

		context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);

		if (context.getPlugins().clientInsertMethodGenerated(method, topLevelClass, introspectedTable)) {
			topLevelClass.addMethod(method);
		}

	}

	/**
	 * @param topLevelClass
	 */
	private void addImportedType(TopLevelClass topLevelClass) {
		topLevelClass.addImportedType(new FullyQualifiedJavaType("java.util.Map"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType("java.util.HashMap"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType(
		        "org.springframework.dao.EmptyResultDataAccessException"));
		topLevelClass
		        .addImportedType(new FullyQualifiedJavaType("org.springframework.jdbc.core.BeanPropertyRowMapper"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType("org.springframework.dao.DataAccessException"));
		FullyQualifiedJavaType modelClass = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
		topLevelClass.addImportedType(modelClass);
	}

}
